import { FormSchema } from '../schema/schema';
import { BuilderHTMLElement } from '@farris/designer-element';
import { ComponentFactoryResolver, Injector } from '@angular/core';
import { BsModalService } from '@farris/ui-modal';
import { FieldManagerComponent } from '@farris/designer-devkit';
import { FormProp } from '../property/property-config';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';
import { RowNode } from '@farris/ui-treetable';
import { FormContextMenuManager } from '../context-menu/context-menu.manager';
import { DgControl } from '../../../../utils/dg-control';
import { FormDragDropManager } from '../drag-drop/dragAndDropManager';
import { DesignerEnvType, DomService, FormComponentType, SchemaService } from '@farris/designer-services';
import { NoCodeFormProp } from '../property/nocode-property-config';
import { TableComponentCreatorContextMenuService } from '../../component/context-menu/services/table-creator.service';

export default class FdFormComponent extends FdContainerBaseComponent {


    triggerBelongedComponentToMoveWhenMoved = true;

    constructor(component: any, options: any) {
        super(component, options);

        this.getCustomToolbarConfig();
    }

    getDefaultSchema(): any {
        return FormSchema;
    }

    getTemplateName(): string {
        return 'Form';
    }

    /**
     * 不支持删除
     */
    checkCanDeleteComponent(): boolean {
        return false;
    }
    /**
     * 判断是否可以接收拖拽新增的子级控件
     */
    canAccepts(sourceElement: BuilderHTMLElement): boolean {
        const dragManager = new FormDragDropManager(this);
        return dragManager.canAccepts(sourceElement);
    }

    /**
     * 移动控件后事件：在可视化设计器中，将现有的控件移动到容器中
     * @param el 移动的源DOM结构
     */
    onAcceptMovedChildElement(sourceElement: BuilderHTMLElement) {
        if (!sourceElement) {
            return;
        }

        const dragManager = new FormDragDropManager(this);
        dragManager.onAcceptMovedChildElement(sourceElement);
    }

    /**
     * 弹出字段维护窗口
     */
    private showFieldManager() {

        // 动态创建相关的服务需要从designerHost中获取
        const serviceHost = this.options.designerHost;
        const resolver = serviceHost.getService('ComponentFactoryResolver') as ComponentFactoryResolver;
        const injector = serviceHost.getService('Injector') as Injector;
        const modalService = serviceHost.getService('ModalService') as BsModalService;
        const schemaService = serviceHost.getService('SchemaService') as SchemaService;

        const compFactory = resolver.resolveComponentFactory(FieldManagerComponent);
        const compRef = compFactory.create(injector);
        const modalConfig = {
            title: '维护控件',
            width: 950,
            height: 600,
            showButtons: true,
            buttons: compRef.instance.modalFooter
        };
        compRef.instance.viewModelId = this.viewModelId;
        compRef.instance.formId = this.component.id;

        compRef.instance.disableFieldsInOtherForm = this.checkIfDisableFieldsInOtherForm();
        const modalPanel = modalService.show(compRef, modalConfig);
        compRef.instance.closeModal.subscribe(() => {
            modalPanel.close();
        });
        compRef.instance.confirmModal.subscribe((data) => {
            const { addedFields, deletedFieldIds } = data;
            if (deletedFieldIds && deletedFieldIds.length) {
                schemaService.removeSchemaField(deletedFieldIds);
            }
            modalPanel.close();
        });

    }
    /**
     * 组装属性面板配置数据
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options.designerHost;

        if (this.envType === DesignerEnvType.noCode) {
            const prop: NoCodeFormProp = new NoCodeFormProp(serviceHost, this.viewModelId, this.componentId);
            const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
            return propertyConfig;
        } else {
            const prop: FormProp = new FormProp(serviceHost, this.viewModelId, this.componentId);
            const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
            return propertyConfig;
        }
    }

    /**
     * 属性变更后
     * @param changeObject 变更集
     */
    onPropertyChanged(changeObject: FormPropertyChangeObject): void {
        super.onPropertyChanged(changeObject, ['formAutoIntl', 'controlsInline', 'labelSize']);
    }

    /**
     * 组装右键菜单
     * @param rowNode 组件在控件树上对应的行数据
     */
    resolveContextMenuConfig(rowNode: RowNode) {
        const menuManager = new FormContextMenuManager(this, rowNode);
        return menuManager.setContextMenuConfig();
    }
    /**
     * 判断在可视化区域中是否隐藏容器间距和线条
     */
    hideNestedPaddingInDesginerView() {
        // 控件本身样式
        const cmpClass = this.component.appearance && this.component.appearance.class || '';
        const cmpClassList = cmpClass ? cmpClass.split(' ') : [];

        // 子级节点
        const childContents = this.component.contents || [];
        const firstChildContent = childContents.length ? childContents[0] : null;
        const firstChildClass = firstChildContent && firstChildContent.appearance ? firstChildContent.appearance.class : '';
        const firstChildClassList = firstChildClass ? firstChildClass.split(' ') : [];

        // 父级节点
        const parent = this.parent && this.parent.component;
        const parentClass = parent && parent.appearance && parent.appearance.class || '';
        const parentClassList = parentClass ? parentClass.split(' ') : [];

        // 1、带导航的表格类填报模板：Form内部为table 时，隐藏间距
        if (cmpClassList.includes('f-form-is-table') && parentClassList.includes('f-section-oa-table') && firstChildClassList.includes('table')) {
            return true;
        }
        // 2、卡片类表格模板：Form内部为table时，隐藏间距
        if (cmpClassList.includes('f-form-is-table') && parentClassList.includes('f-section-card-table') && firstChildClassList.includes('table')) {
            return true;
        }

    }

    getDragScopeElement(): HTMLElement {
        const domService = this.options.designerHost.getService('DomService') as DomService;

        // 判断是否为弹窗内部的组件，若是，则限定控件的拖拽不能超出弹出区域
        const rootCmps = domService.module.components.filter(c => c.componentType === FormComponentType.modalFrame);
        if (!rootCmps || rootCmps.length === 0) {
            return;
        }

        let rootCmpId;
        for (const cmp of rootCmps) {
            const cmpRefNode = domService.selectNode(cmp, n => n.type === DgControl.ComponentRef.type && n.component === this.componentId);
            if (cmpRefNode) {
                rootCmpId = cmp.id;
                break;
            }
        }
        if (rootCmpId) {
            const rootContainer = document.getElementById(rootCmpId);
            return rootContainer;
        }
    }


    private getCustomToolbarConfig() {
        this.customToolbarConfigs = [];

        // 内部不包含table控件时展示字段维护图标
        const tableChild = this.component.contents && this.component.contents.length && this.component.contents.find(c => c.type === DgControl.Table.type);
        if (!tableChild) {
            this.customToolbarConfigs.push(
                {
                    id: 'fieldManager',
                    title: '字段维护',
                    icon: 'f-icon f-icon-home-setup',
                    click: (e) => {
                        e.stopPropagation();
                        this.showFieldManager();
                    }
                });
        }

        // 零代码支持将Form切换为Table
        if (this.envType === DesignerEnvType.noCode) {
            const injector = this.options.designerHost.getService('Injector');
            const belongedComponentInstance = this.getBelongedComponentInstance(this);
            if (belongedComponentInstance) {
                const tableCreatorServ = new TableComponentCreatorContextMenuService(injector, belongedComponentInstance);
                if (tableCreatorServ.checkCanChangeToTableComponent()) {
                    this.customToolbarConfigs.push(
                        {
                            id: 'changeFormToTable',
                            title: '切换为表格',
                            icon: 'f-icon f-icon-table-properties',
                            click: (e) => {
                                e.stopPropagation();
                                this.changeFormComponentToTableComponent();
                            }
                        });
                }
            }
        }

    }

    /**
     * Form组件切换为Table组件
     */
    private changeFormComponentToTableComponent() {
        const injector = this.options.designerHost.getService('Injector');
        const belongedComponentInstance = this.getBelongedComponentInstance(this);

        const tableCreatorServ = new TableComponentCreatorContextMenuService(injector, belongedComponentInstance);
        tableCreatorServ.changeFormComponentToTableComponent();


    }
    /**
     * 是否将在其他卡片中出现的字段禁用掉
     */
    private checkIfDisableFieldsInOtherForm() {
        // 在侧边栏中的字段是可以与画布中的字段重复出现的
        const belongedCmp = this.getBelongedComponentInstance(this);
        const cmpRef = belongedCmp && belongedCmp.parent;
        if (cmpRef && cmpRef.parent && cmpRef.parent.type === DgControl.Sidebar.type) {
            return false;
        }

        // 其他场景下，不允许多个卡片中重复添加一个字段
        return true;
    }
}
